<template>
  <div class="y2048 flex-center">
    <div class="game-board">
    </div>
    <RankList />
  </div>
</template>

<script setup lang="ts">
import { setScore } from "@/api/modules/game";
import Grid from "./js/Grid";
import Tile from "./js/Tile";
const route = useRoute()
onMounted(() => {
  const gameBoard = document.querySelector(".game-board") as HTMLDivElement;
  const grid = new Grid(gameBoard);

  grid.randomEmptyCell().tile = new Tile(gameBoard);
  grid.randomEmptyCell().tile = new Tile(gameBoard);
  console.log(grid);
  const initScore = grid.cells.reduce(
    (total, cell) => total + (cell.tile?.value || 0),
    0
  );
  console.log(initScore);

  console.log(grid.cellsByColumn);
  console.log(grid.cellsByRow);

  setupInput();
  function setupInput() {
    window.addEventListener("keydown", handleKeydown, { once: true }); //只执行一次，动画结束时重新监听
  }

  async function handleKeydown(e: KeyboardEvent) {
    switch (e.key) {
      case "ArrowUp":
        if (!canMoveUp()) {
          setupInput();
          return;
        }
        await moveUp();
        break;
      case "ArrowDown":
        if (!canMoveDown()) {
          setupInput();
          return;
        }
        await moveDown();
        break;
      case "ArrowLeft":
        if (!canMoveLeft()) {
          setupInput();
          return;
        }
        await moveLeft();
        break;
      case "ArrowRight":
        if (!canMoveRight()) {
          setupInput();
          return;
        }
        await moveRight();
        break;
      default:
        setupInput();
        return;
    }
    grid.cells.forEach((cell) => cell.mergeTiles());
    const newTile = new Tile(gameBoard);
    grid.randomEmptyCell().tile = newTile;

    if (!canMoveUp() && !canMoveDown() && !canMoveLeft() && !canMoveRight()) {
      newTile.waitForTransition(true).then(() => {
        const score =
          grid.cells.reduce(
            (total, cell) => total + (cell.tile?.value || 0),
            0
          ) - initScore;
        setScore({ game_id: route.query.id as string, label: "" + score, score })
        alert("Game Over，您的总分为：" + score);
      });
      return;
    }

    setupInput();
  }

  function moveUp() {
    slideTiles(grid.cellsByColumn);
  }
  function moveDown() {
    slideTiles(
      grid.cellsByColumn.map((column: any) => column.slice().reverse())
    );
  }
  function moveLeft() {
    slideTiles(grid.cellsByRow);
  }
  function moveRight() {
    slideTiles(grid.cellsByRow.map((row: any) => row.slice().reverse()));
  }

  function canMoveUp() {
    return canMove(grid.cellsByColumn);
  }
  function canMoveDown() {
    return canMove(
      grid.cellsByColumn.map((column: any) => column.slice().reverse())
    );
  }
  function canMoveLeft() {
    return canMove(grid.cellsByRow);
  }
  function canMoveRight() {
    return canMove(grid.cellsByRow.map((row: any) => row.slice().reverse()));
  }

  function canMove(cells: any[]) {
    return cells.some((group: any) =>
      group.some((cell: any, index: number) => {
        if (!(index && cell.tile)) {
          return false;
        }

        const moveToCell = group[index - 1];
        return moveToCell.canAccept(cell.tile);
      })
    );
  }

  function slideTiles(cells: any[]) {
    console.log("xxx", cells);
    return Promise.all(
      cells.flatMap((group) => {
        const promises = [];
        for (let i = 1; i < group.length; i++) {
          const cell = group[i];
          if (!cell.tile) continue;
          let lastValidCell;
          for (let j = i - 1; j >= 0; j--) {
            const moveToCell = group[j];
            if (!moveToCell.canAccept(cell.tile)) break;
            lastValidCell = moveToCell;
          }

          if (lastValidCell) {
            promises.push(cell.tile.waitForTransition(true));
            if (lastValidCell.tile) {
              lastValidCell.mergeTile = cell.tile;
            } else {
              lastValidCell.tile = cell.tile;
            }
            cell.tile = null;
          }
        }
        return promises;
      })
    );
  }
});
</script>

<style lang="scss">
.game-board {
  .cell {
    background-color: #aaa;
    border-radius: 1vmin;
  }

  .tile {
    position: absolute;
    width: var(--cell-size);
    height: var(--cell-size);
    border-radius: 1vmin;
    top: calc(var(--y) * (var(--cell-size) + var(--cell-gap)) + var(--cell-gap));
    left: calc(var(--x) * (var(--cell-size) + var(--cell-gap)) + var(--cell-gap));
    font-weight: bold;
    background-color: hsl(200, 50%, var(--background-lightness));
    color: hsl(200, 25%, var(--text-lightness));
    text-align: center;
    line-height: var(--cell-size);
    animation: show 200ms ease-in-out;
    transition: 100ms ease-in-out;
  }

  @keyframes show {
    0% {
      opacity: 0.5;
      transform: scale(0);
    }
  }
}
</style>
<style scoped lang="scss">
@import "./index.scss";
</style>
